/*
 * @Description: 新增规则弹窗
 * @Author: Rfan
 * @Date: 2022-04-14 18:03:21
 * @LastEditTime: 2023-01-06 16:17:43
 */

import { useCallback, useEffect, useState } from 'react';
import { Button, message, Modal, Tree } from 'antd';
import classNames from 'classnames/bind';
import { arrToTree, findParentNodeById } from '@/utils';
import { fetchFunctionalRightsList } from '@/api/right';
import { fetchRoleFunctionalList, saveRoleFunction } from '@/api/role';
import { delItemByIdArray } from '@/utils/list';
import { useRoleContext } from '../../../contexts/RoleContext';
import type { ICommonDialog } from '@/interfaces/global';
import type { FC, Key } from 'react';
import styles from './styles/index.module.scss';

const cx = classNames.bind(styles);

const FunctionRightsDialog: FC<ICommonDialog> = (props) => {
  const { visible, onClose } = props;
  const { selectRoleId } = useRoleContext();
  // 变更Flag
  const [changeFlag, setChangeFlag] = useState(false);
  // 扁平权限列表
  const [flatTreeData, setFlatTreeData] = useState([]);
  // 全部功能权限列表，用于树展示
  const [treeData, setTreeData] = useState([]);
  // 角色已有的权限列表
  const [checkedList, setCheckedList] = useState([]);
  // 保存按钮Loading
  const [btnLoading, setBtnLoading] = useState(false);

  useEffect(() => {
    if (visible) {
      const listPromise = fetchFunctionalRightsList({});
      const rightsPromise = fetchRoleFunctionalList({ roleId: selectRoleId });
      Promise.all([listPromise, rightsPromise]).then(([listRes, rightsRes]) => {
        const { data } = listRes;
        setFlatTreeData(data);
        setTreeData(arrToTree(data));
        // 活期叶子节点id
        const leafNodesId = getLeafNode(data || []);
        // 筛选出选中的叶子节点id
        setCheckedList(
          rightsRes.data
            .map((item: any) => item.rightsId)
            .filter((item: any) => leafNodesId.indexOf(item) >= 0)
        );
      });
    } else if (checkedList.length > 0) {
      setCheckedList([]);
    }
  }, [visible]);

  const memoizedClose = useCallback(() => onClose(), []);

  const getLeafNode = (nodeList: any[]) => {
    const pidArr = nodeList.filter((item) => item.pid).map((item) => item.pid);
    return delItemByIdArray(Array.from(new Set(pidArr)), nodeList).map((node: any) => node.id);
  };

  /**
   * @description: 关闭弹窗
   */
  const onCancel = () => {
    setChangeFlag(false);
    memoizedClose();
  };

  /**
   * @description: 选择树节点回调
   * @param {Key[]} checkedKeys 选中的节点
   */
  const onCheck = (checkedKeys: Key[]) => {
    setCheckedList(checkedKeys);
    setChangeFlag(true);
  };

  /**
   * @description: 保存选中的权限
   */
  const saveRights = () => {
    const allKeys = new Set();
    checkedList.forEach((id) => {
      const parentIds: number[] = findParentNodeById(flatTreeData, parseInt(id as string, 10)).map(
        (node) => node.id
      );
      parentIds.forEach((pid) => {
        allKeys.add(pid);
      });
    });

    setBtnLoading(true);
    const params = {
      roleId: selectRoleId,
      rightsIdList: Array.from(allKeys)
    };
    saveRoleFunction(params)
      .then(() => {
        message.success('保存成功');
        onCancel();
      })
      .finally(() => {
        setBtnLoading(false);
      });
  };

  return (
    <Modal
      title="功能权限设置"
      visible={visible}
      width={500}
      destroyOnClose
      onCancel={onCancel}
      footer={[
        <Button key="close" onClick={onCancel}>
          取消
        </Button>,
        <Button
          key="save"
          type="primary"
          disabled={!changeFlag}
          loading={btnLoading}
          onClick={saveRights}
        >
          保存
        </Button>
      ]}
    >
      <div className={cx('functional-tree')}>
        {/* 增加 checkStrictly 属性切断父子联系
            父子节点需要单独选择
            onCheck 方法参数会有变化
        */}
        {treeData.length > 0 && (
          <Tree
            key="id"
            checkable
            autoExpandParent
            selectable={false}
            checkedKeys={checkedList}
            onCheck={onCheck}
            treeData={treeData}
            fieldNames={{ key: 'id', title: 'rightsName' }}
          />
        )}
      </div>
    </Modal>
  );
};

export default FunctionRightsDialog;
